package com.foreveross.proxyip.core.pools;

import java.util.List;

import org.apache.commons.lang3.StringUtils;

import com.dayatang.domain.InstanceFactory;
import com.foreveross.proxyip.core.BaseCode;
import com.foreveross.proxyip.core.http.ipdoload.IpDoloadManager;
import com.foreveross.proxyip.core.pools.thread.CircleThread;
import com.foreveross.proxyip.core.pools.thread.publ.PublicCheckInThread;
import com.foreveross.proxyip.core.pools.thread.publ.PublicCheckOutThread;
import com.foreveross.proxyip.core.pools.validate.PublicTestProxyIp;
import com.foreveross.proxyip.core.redis.PiRedisExecption;
import com.foreveross.proxyip.core.zk.task.doLoad.IDoLoad;
import com.foreveross.proxyip.entity.ProxyIpBean;
import com.foreveross.proxyip.exception.ProxyIpServiceException;
/**
 * 公共池
 * @author lyq
 *
 */
public class PublicPool extends AvailablePool implements IDoLoad {
	
	public final static String POOL_CODE = "public";
	
	private IpDoloadManager ipDoloadManager;
	
	
	/*******ip实例集合，map类型保证了池中ip的唯一性
	 * @throws PiRedisExecption 
	 * @throws NumberFormatException ********/
	public PublicPool() throws NumberFormatException, PiRedisExecption {
		super("公共池",POOL_CODE);
		validate = new PublicTestProxyIp(this.poolSign);
		initBaseCode();
		this.offerWaitTime = 10000;
		//super.threadNum = Runtime.getRuntime().availableProcessors() * 2;
		log.info("PublicPool thread begin");
	}
	
	@Override
	public void initChannelProperty() {
		// TODO Auto-generated method stub
		
	}


	@Override
	public void initBaseCode() throws NumberFormatException, PiRedisExecption {
		super.proxyMax = Long.parseLong(BaseCode.getValue("PUBLIC_PROXY_MAX")); 
		super.threadMaxIpCount = Integer.parseInt(BaseCode.getValue("PUBLIC_THREAD_MAX_IP_COUNT"));
		super.sourceNum = Long.parseLong(BaseCode.getValue("PUBLIC_SOURCE_NUM"));
//		super.sourceTask = BaseCode.getValue("PUBLIC_SOURCE_TASK");
//		super.sourceCache = BaseCode.getValue("PUBLIC_SOURCE_CACHE");
		super.proxyMin = Long.parseLong(BaseCode.getValue("PUBLIC_PROXY_MIN")); 
		
		// 线程定时检查时间间隔
		super.checkInInterval = Long.parseLong(BaseCode.getValue("PUBLIC_IN_SEPARATION_TIME"));
		super.checkOutInterval = Long.parseLong(BaseCode.getValue("PUBLIC_OUT_SEPARATION_TIME"));
		
		this.validate.setConfig();
	}

	
	/**
	 * ip放进池里
	 * @param ip
	 * @param proxyIpBean
	 * @throws PiRedisExecption 
	 */
	public void set(ProxyIpBean proxyIpBean) throws PiRedisExecption{
		if(!poolIpMap.containsKey(proxyIpBean.getCompletionIP())){//已经存在了
			proxyIpBean.getUsingKeys().add(this.poolSign);
			poolIpMap.set(proxyIpBean.getCompletionIP());
		}
	}
	
	public void checkIn() {
		CircleThread run = null;
		Thread checkInTh = null;

		try {
			for (int i = 0; i < threadNum; i++) {
				run = new PublicCheckInThread(this);
				checkInTh = new Thread(run, this.poolSign + "-checkin-" + i);
				this.checkInThs.add(checkInTh);
				checkInTh.start();
			}

		} catch (Exception e) {
			log.error(e.getMessage(), e);
			System.exit(0);
		}
	}
	
	public void checkOut(){
		CircleThread run = null;
		Thread checkOutTh = null;
		// 检出线程比检入少一半
		int outThreadNum = threadNum / 2;
		outThreadNum = outThreadNum == 0 ? 1 : outThreadNum;

		try {
			for (int i = 0; i < outThreadNum; i++) {
				run = new PublicCheckOutThread(this, this.getRepository());
				checkOutTh = new Thread(run, this.poolSign + "-checkout-" + i);
				this.checkOutThs.add(checkOutTh);
				checkOutTh.start();
			}
		} catch (Exception e) {
			log.error(ProxyIpServiceException.getStackTrace(e));
		}
	}
	

	public IpDoloadManager getIpDoloadManager(){
		if(ipDoloadManager==null){
			 ipDoloadManager = InstanceFactory.getInstance(IpDoloadManager.class);
		}
		return ipDoloadManager;
	}
	

//	@SuppressWarnings("unchecked")
//	@Override
//	protected List<ProxyIpBean> lastProcess(List returnList,String poolCode) throws Exception  {
//		if(StringUtils.isNotBlank(poolCode)){
//			for(int i=0;i<returnList.size();i++){
//				ProxyIpBean ip = (ProxyIpBean)returnList.get(i);
//				lastProcessAction(ip,poolCode);
//			}
//		}
//		return returnList;
//	}
	
	public void lastProcessAction(ProxyIpBean bean,String poolCode) throws Exception{
		if(StringUtils.isNotBlank(poolCode)){
//			bean.getUsingKeys().add(poolCode);//这一步在set设置
		}
	}


	@SuppressWarnings("unchecked")
	@Override
	public List<ProxyIpBean> download(Long num) throws Exception {
		return this.getIpDoloadManager().extract(num);
		
	}
	
}
